home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
dev
/
lang
/
PPCSmllEiffel.lha
/
PPCSmallEiffel
/
lib_se
/
parent_list.e
< prev
next >
Wrap
Text File
|
1998-01-16
|
12KB
|
636 lines
-- This file is part of SmallEiffel The GNU Eiffel Compiler.
-- Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
-- Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
-- http://www.loria.fr/SmallEiffel
-- SmallEiffel is free software; you can redistribute it and/or modify it
-- under the terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 2, or (at your option) any later
-- version. SmallEiffel is distributed in the hope that it will be useful,but
-- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-- for more details. You should have received a copy of the GNU General
-- Public License along with SmallEiffel; see the file COPYING. If not,
-- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-- Boston, MA 02111-1307, USA.
--
class PARENT_LIST
--
-- To store the parent list of a class.
--
inherit GLOBALS;
creation make
feature
base_class: BASE_CLASS;
-- Where the parent list is written.
start_position: POSITION;
-- Of the keyword "inherit".
heading_comment: COMMENT;
-- Global comment of the inherit clause.
feature {NONE}
list: ARRAY[PARENT];
feature
make(bc: like base_class; sp: like start_position;
hc: like heading_comment; l: like list) is
require
bc /= Void;
sp /= Void;
l.lower = 1 and not l.empty;
do
base_class := bc;
heading_comment := hc;
start_position := sp;
list := l;
ensure
base_class = bc;
start_position = sp;
heading_comment = hc;
list = l;
end;
count: INTEGER is
do
Result := list.upper;
end;
up_to_any_in(pl: FIXED_ARRAY[BASE_CLASS]) is
local
i: INTEGER;
p: PARENT;
bc: BASE_CLASS;
do
from
i := list.upper;
until
i = 0
loop
p := list.item(i);
bc := p.type.base_class;
if not pl.fast_has(bc) then
pl.add_last(bc);
end;
i := i - 1;
end;
from
i := list.upper;
until
i = 0
loop
p := list.item(i);
bc := p.type.base_class;
if bc /= class_any then
bc.up_to_any_in(pl);
end;
i := i - 1;
end;
end;
base_class_name: CLASS_NAME is
do
Result := base_class.base_class_name;
end;
has_redefine(fn: FEATURE_NAME): BOOLEAN is
require
fn /= Void
local
i: INTEGER;
do
from
i := 1;
until
Result or else i > list.upper
loop
Result := list.item(i).has_redefine(fn);
i := i + 1;
end;
end;
super: PARENT is
require
count = 1
do
Result := list.first;
end;
feature {TYPE}
smallest_ancestor(ctx: TYPE): TYPE is
require
ctx.is_run_type;
local
i: INTEGER;
p: PARENT;
sa: TYPE;
do
from
i := list.upper;
until
i = 0
loop
p := list.item(i);
sa := p.smallest_ancestor(ctx).run_type;
if Result = Void then
Result := sa;
else
Result := sa.smallest_ancestor(Result);
end;
if Result.is_any then
i := 0;
else
i := i - 1;
end;
end;
ensure
Result.is_run_type;
end;
feature {BASE_CLASS}
up_to_original(bottom: BASE_CLASS; top_fn: FEATURE_NAME): FEATURE_NAME is
local
p1, p2: PARENT;
fn1, fn2, new_fn: FEATURE_NAME;
i: INTEGER;
do
from
i := list.upper;
until
i = 0 or else fn1 /= Void
loop
p1 := list.item(i);
fn1 := p1.up_to_original(bottom,top_fn);
i := i - 1;
end;
from
until
i = 0
loop
p2 := list.item(i);
fn2 := p2.up_to_original(bottom,top_fn);
if fn2 /= Void then
new_fn := p2.do_rename(top_fn);
if p2.has_select_for(new_fn) then
p1 := p2;
fn1 := fn2;
end;
end;
i := i - 1;
end;
if fn1 /= Void then
if fn1.to_string /= top_fn.to_string then
Result := repeated_inheritance(p1,fn1,top_fn);
else
Result := fn1;
end;
end;
end;
clients_for(fn: FEATURE_NAME): CLIENT_LIST is
require
fn /= Void
local
i: INTEGER;
cl: CLIENT_LIST;
do
from
i := list.upper;
until
i = 0
loop
cl := list.item(i).clients_for(fn);
if Result = Void then
Result := cl;
elseif cl /= Void then
Result := Result.append(cl);
end;
if Result /= Void and then Result.gives_permission_to_any then
i := 0;
else
i := i - 1;
end;
end;
ensure
Result /= Void
end;
going_up(trace: FIXED_ARRAY[PARENT]; top: BASE_CLASS;
top_fn: FEATURE_NAME;): FEATURE_NAME is
require
top /= Void;
top_fn /= Void
local
i: INTEGER;
p1, p2: PARENT;
fn1, fn2: FEATURE_NAME;
do
from
i := list.upper;
until
fn1 /= Void or else i = 0
loop
p1 := list.item(i);
fn1 := p1.going_up(trace,top,top_fn);
i := i - 1;
end;
from
until
i = 0
loop
p2 := list.item(i);
fn2 := p2.going_up(trace,top,top_fn);
if fn2 /= Void then
if p2.has_select_for(fn2) then
p1 := p2;
fn1 := fn2;
end;
end;
i := i - 1;
end;
Result := fn1;
end;
is_a_vncg(t1, t2: TYPE): BOOLEAN is
require
t1.run_type = t1;
t2.run_type = t2;
t2.generic_list /= Void;
eh.empty
local
i: INTEGER;
do
from
i := list.upper;
until
Result or else i = 0
loop
Result := list.item(i).is_a_vncg(t1,t2);
i := i - 1;
end;
ensure
eh.empty
end;
has(fn: FEATURE_NAME): BOOLEAN is
local
i: INTEGER;
do
from
i := list.upper;
until
Result or else i = 0
loop
Result := list.item(i).has(fn);
i := i - 1;
end;
end;
collect_invariant(rc: RUN_CLASS) is
require
rc /= Void
local
i: INTEGER;
do
from
i := list.upper;
until
i = 0
loop
list.item(i).type.base_class.collect_invariant(rc);
i := i - 1;
end;
end;
inherit_cycle_check is
local
i: INTEGER;
p: PARENT;
bc: BASE_CLASS;
do
from
i := list.upper;
until
i = 0
loop
p := list.item(i);
bc := p.type.base_class;
if bc = Void then
eh.add_position(p.start_position);
fatal_error(fz_cnf);
else
bc.inherit_cycle_check;
end;
i := i - 1;
end;
end;
has_parent(c: BASE_CLASS): BOOLEAN is
require
not c.is_any
local
i: INTEGER;
bc: BASE_CLASS;
do
from
i := list.upper;
until
i = 0
loop
bc := list.item(i).type.base_class;
if c = bc then
Result := true;
i := 0;
elseif bc.is_subclass_of_aux(c) then
Result := true;
i := 0;
else
i := i - 1;
end;
end;
end;
feature {BASE_CLASS}
first_parent_for(c: BASE_CLASS): PARENT is
-- Gives the first parent going to `c'.
local
i: INTEGER;
pbc: BASE_CLASS;
do
from
i := 1;
until
Result /= Void
loop
Result := list.item(i);
pbc := Result.type.base_class;
if pbc = c then
elseif pbc.is_subclass_of(c) then
else
Result := Void;
end;
i := i + 1;
end;
ensure
Result /= Void
end;
next_parent_for(c: BASE_CLASS; previous: PARENT): like previous is
-- Gives the next one or Void.
local
i: INTEGER;
pbc: BASE_CLASS;
do
from
from
i := 1;
until
Result = previous
loop
Result := list.item(i);
i := i + 1;
end;
Result := Void;
until
Result /= Void or else i > list.count
loop
Result := list.item(i);
pbc := Result.type.base_class;
if pbc = c then
elseif pbc.is_subclass_of(c) then
else
Result := Void;
end;
i := i + 1;
end;
end;
feature {BASE_CLASS}
header_comment_for(ci: CLASS_INVARIANT) is
local
i: INTEGER;
do
from
i := list.upper;